unit uFormMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, StdCtrls, ComCtrls, StrUtils;

const
  WM_KILLBTN = WM_APP + 1;

type
  TForm1 = class(TForm)
    TabControl1: TTabControl;
    procedure FormCreate(Sender: TObject);
  private
    procedure UpdateButtonRect(aButton: TSpeedButton; aIndex: Integer );
    procedure CreateCloseButtons;
    procedure UpdateButtonList;
    procedure OnCloseBtnClick( Sender: TObject );
    procedure OnKillBtn( var AMsg: TMessage ); message WM_KILLBTN;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  CreateCloseButtons;
end;

procedure TForm1.CreateCloseButtons;
var
  i: Integer;
  lBtn: TSpeedButton;
begin
  for i := 0 to pred( TabControl1.Tabs.Count ) do
  begin
    lBtn := TSpeedButton.Create(Self );
    lBtn.Caption := 'x';
    UpdateButtonRect( lBtn, i );
    lBtn.Parent := TabControl1;
    lBtn.OnClick := OnCloseBtnClick;
    lBtn.Tag := i;
    lBtn.Flat := True;
    lBtn.Transparent := True;
    TabControl1.Tabs.Objects[i] := lBtn;
  end;
end;

procedure TForm1.OnCloseBtnClick(Sender: TObject);
var
  lBtn: TSpeedButton;
begin
  lBtn := TSpeedButton(Sender);
  TabControl1.Tabs.Delete( lBtn.Tag );
  PostMessage( Self.Handle, WM_KILLBTN, Integer(lBtn), 0 );
end;

procedure TForm1.OnKillBtn(var AMsg: TMessage);
begin
  TSpeedButton( AMsg.wParam ).Free;
  UpdateButtonList;
end;

procedure TForm1.UpdateButtonList;
var
  i: Integer;
  lBtn: TSpeedButton;
begin
  for i := 0 to Pred( TabControl1.Tabs.Count ) do
  begin
    lBtn := TSpeedButton(TabControl1.Tabs.Objects[i]);
    lBtn.Tag := i;
    UpdateButtonRect( lBtn, i );
  end;
end;

procedure TForm1.UpdateButtonRect(aButton: TSpeedButton; aIndex: Integer);
const
  lC_Ident = 2;
  lC_2Ident = lC_Ident * 2;
var
  lRect: TRect;
  lInt: Integer;
begin
  lRect := TabControl1.TabRect(aIndex);
  lInt := lRect.Bottom - lRect.Top - lC_2Ident;
  with lRect do
    lRect := Rect( Right - lInt - lC_Ident, Top + lC_Ident, Right-lC_Ident, Bottom - lC_Ident );
  aButton.BoundsRect := lRect;
end;

end.
